package threads;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.TimerTask;
import java.util.logging.Level;

import model.Player;
import model.Preference;
import model.Settings;
import model.feature.FeaturePlayer;
import model.inventory.InventoryPlayer;
import net.HTTPDownloader;
import net.HttpRequestFacade;
import util.LoggingUtils;
import util.PlayerUtilities;
import view.content.ImageBox;
import cmd.RemoteCommandExecutor;

public class Updater extends TimerTask implements Runnable {

	private Player player;
	//RBB
	protected final String className = this.getClass().getName();

	public Updater(Player p) {
		this.player = p;
	}

	@Override	
	public void run() {
		String classMethod = className + ".run()";
		LoggingUtils.logStart(classMethod + " which should run indefinitely");
		while (true) {
			try {
				if (Updater.this.hasNewUpdate()) {
					String remoteFile = Settings.DMB_DOMAIN + "/webtool/boxdata/" + Preference.getInstance().getBoxID()
							+ "/" + Settings.RESOURCES_FILENAME;
					LoggingUtils.logStart("download of remoteFile " + remoteFile + " in " + classMethod);
					boolean downloaded = HTTPDownloader.getInstance().download(remoteFile, Settings.RESOURCES_FILENAME);
					if (downloaded) {
						PlayerUtilities.resetUpdateStringJson();
						HttpRequestFacade.postUpdateComplete();
						//System.out.println("downloaded update: " + remoteFile);
						PlayerUtilities.unzip(new File(Settings.RESOURCES_FILENAME), new File("."));

						Updater.this.executeCommands(); // Executing command here d
						InventoryPlayer.getInstance().update();
						FeaturePlayer.getInstance().update();
						ImageBox.resetImageStore();							// Reseting image store
						Updater.this.player.update();
						Updater.this.player.downloadContents();
						System.out.println("update complete....");
						Player.getInstance().save();
						Preference.getInstance().save();
						
						LoggingUtils.log(Level.SEVERE, "Successfully downloaded remote file " + remoteFile 
								+ " in " + classMethod);
						// -------------- testing purpose -----------
						//String jsonparameter = PlayerUtilities.getUpdateStringJson().toJSONString();
						//System.out.println(jsonparameter);
						//HttpRequestFacade.postContentUpdateConfirmation(jsonparameter);
						updatePlayerConfirmationJSon();
						//PlayerUtilities.resetUpdateStringJson();
					}
				} else {
					LoggingUtils.log(Level.INFO, "Cannot download a remote file in " + classMethod 
							+ " because Updater has no new updates. Waiting indefinitely for new update files");
				}
			} catch (MalformedURLException e1) {
				LoggingUtils.log(Level.SEVERE, "Cannot download remote files for updates in " + classMethod, e1);
				//e1.printStackTrace();
			}
			catch (Exception e1) {
				
				LoggingUtils.log(Level.SEVERE, "Cannot download remote files for updates in " + classMethod, e1);
				//e1.printStackTrace();
			}
			
			try {
				Thread.sleep(Preference.getInstance().getUpdateCheckerFrequency() * 1000);
			} catch (InterruptedException e) {
				LoggingUtils.log(Level.SEVERE, "Cannot sleep for interval " 
						+ (Preference.getInstance().getUpdateCheckerFrequency() * 1000)
						+ " in " + classMethod + " because it was interrupted", e);
				e.printStackTrace();
			}
		}
	}
	
	
	private void updatePlayerConfirmationJSon()
	{
		Thread jsonThread = new Thread(new Runnable() {
			@Override
			public void run() {
				String jsonparameter = PlayerUtilities.getUpdateStringJson().toJSONString();
				System.out.println(jsonparameter);
				HttpRequestFacade.postContentUpdateConfirmation(jsonparameter);
				PlayerUtilities.resetUpdateStringJson();
			}
		});
		jsonThread.setName("PlayerUpdateConfirmation");
		jsonThread.start();
	}

	public boolean hasNewUpdate() throws MalformedURLException {
		if(!Preference.getInstance().isCheckUpdates())
			return false;
		try
		{
			URL url = new URL(Settings.UPDATE_CHECKER_URL);
			String data = net.HttpPostConnector.getBoxToken() + "&reqtype=checkupdate";
			System.out.println(Settings.UPDATE_CHECKER_URL+"/"+data);
			net.HttpPostConnector conn = new net.HttpPostConnector(url, data);
			conn.post();
			if (conn.getResult() != null && conn.getResult().contains("true")) {
				return true;
			} 
		}
		catch(Exception e)
		{
			LoggingUtils.log(Level.SEVERE, "HasNewUpdate inside Updater.java ", e);
			e.printStackTrace();
		}
		return false;
	}

	private void executeCommands() {
		try {
			RemoteCommandExecutor.getInstance().executeCommands();
			//System.out.println("EXECUTE COMMANDS");
		} catch (Exception e) {
			System.err.println(Thread.currentThread().getName() + " error while executing commands.");
			e.printStackTrace();
			
			final String classMethod = className + ".executeCommands()";
			LoggingUtils.logStart(classMethod);
			LoggingUtils.log(Level.SEVERE,e.getMessage()+" error while executing commands."+classMethod,e);
		}
	}
}
